/*
 * TDS PEC 4
 * Grupo 3H2M
 *
 * El paquete <code>edu.uoc.tds.pec4.server.impl</code> agrupa todas las clases
 * que encapsulan la implementación de los métodos de acceso RMI y el servidor.
 */
package edu.uoc.tds.pec4.server.impl;

import edu.uoc.tds.pec4.beans.AulaDTO;
import edu.uoc.tds.pec4.beans.LocalizacionDTO;
import edu.uoc.tds.pec4.beans.SolicitudDTO;
import edu.uoc.tds.pec4.beans.ReservaDTO;
import edu.uoc.tds.pec4.common.filters.FiltroFechasHoras;
import edu.uoc.tds.pec4.common.util.Constantes;
import edu.uoc.tds.pec4.rmi.GestorAulasInterface;
import edu.uoc.tds.pec4.server.bbdd.DAOFactory;
import edu.uoc.tds.pec4.server.bbdd.ISolicitudDAO;
import edu.uoc.tds.pec4.server.bbdd.IReservaDAO;
import edu.uoc.tds.pec4.server.bbdd.exceptions.DAOFactoryException;
import edu.uoc.tds.pec4.server.bbdd.exceptions.DataBaseDAOException;
import edu.uoc.tds.pec4.server.bbdd.exceptions.GestorAulasException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.List;

/**
 * La clase <code>GestorAulasImpl</code> contiene la implementación de
 * todos los  métodos indicados en la interfaz <code>GestorAulasInterface</code><br />
 * Clase que implementa todas las funciones remotas que se pueden solicitar por RMI
 * y que tienen que ver con el subsistema de Aulas. <br />
 *
 * Representa el objeto remoto que se invoca en la comunicación RMI para los 
 * servicios del subsistema de Aulas
 *
 * @author	Luis Rodríguez-Manzaneque Sánchez
 * @version	25/11/2011
 * @see		edu.uoc.tds.pec4.common.GestorAulasInterface
 */
public class GestorAulasImpl extends UnicastRemoteObject implements GestorAulasInterface {

    /**
     * Constructor
     * @throws	RemoteException en caso de producirse un fallo de comunicaciones
     */
    public GestorAulasImpl() throws RemoteException {
        super();
    }

    /**
     * Devuelve la lista de solicitudes
     * @return  La lista de todas las solicitudes de la aplicación
     * @throws  RemoteException en caso de producirse un fallo de comunicaciones
     * @throws  GestorAulasException En caso de producirse un error en el acceso
     *          a datos
     */
    @Override
    public List<SolicitudDTO> listaSolicitudes() throws GestorAulasException, RemoteException {
        List<SolicitudDTO> solicitudes = new ArrayList<SolicitudDTO>();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            solicitudes = dao.listaSolicitudes();

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_SOLICITUDES
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_SOLICITUDES
                    + Constantes.SL + daoE.getMessage());
        }
        return solicitudes;
    }

    /**
     * Obtiene un listado de la base de datos con todas las solicitudes que cumplen
     * con los filtros establecidos.
     * @param pais      El país por el que se quiere filtrar
     * @param provincia La provincia por la que se quiere filtrar
     * @param ciudad    La ciudad por la que se quiere filtrar
     * @param tiposSol  Un array con la lista de tipos de solicitudes elegidas
     * @param estados   Un array con la lista de los estados de la solicitud
     * @return La lista de las solicitudes filtradas por localización, tipos
     * y/o estados
     * @throws RemoteException
     * @throws GestorAulasException
     */
    @Override
    public List<SolicitudDTO> listaSolicitudes(LocalizacionDTO local,
            List<Integer> tiposSol, List<Integer> estados) throws
            GestorAulasException, RemoteException {
        List<SolicitudDTO> solicitudes = new ArrayList<SolicitudDTO>();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            solicitudes = dao.listaSolicitudes(local,tiposSol,estados);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_SOLICITUDES
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_SOLICITUDES
                    + Constantes.SL + daoE.getMessage());
        }
        return solicitudes;
    }

    /**
     * Obtiene la solicitud de la que se envía por parámetro su identificador
     * @param idSolicitud      El identificador de solicitud
     * @return La solicitud de la que se quieren obtener todos sus datos
     * @throws RemoteException
     * @throws GestorAulasException
     */
    @Override
    public SolicitudDTO getSolicitud(int idSolicitud) throws RemoteException,
            GestorAulasException {

        SolicitudDTO solicitud = new SolicitudDTO();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            solicitud = dao.getSolicitud(idSolicitud);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_CONSULTA_SOLICITUD
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_CONSULTA_SOLICITUD
                    + Constantes.SL + daoE.getMessage());
        }
        return solicitud;
    }
    
    
    /**
     * Devuelve la lista de Solicitudes que existen actualmente.
     * @return  La lista de todos los Solicitudes de la aplicación
     * @throws RemoteException
     * @throws GestorAulasException
     */
    public List<AulaDTO> listaAulasLibres(int idCiudad, FiltroFechasHoras fechasHoras) 
            throws RemoteException,GestorAulasException {

        List<AulaDTO> aulas = new ArrayList<AulaDTO>();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            IReservaDAO dao = factory.getReservaDAO();
            aulas = dao.listaAulasLibres(idCiudad, fechasHoras);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_AULASLIBRES
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_AULASLIBRES
                    + Constantes.SL + daoE.getMessage());
        }
        return aulas;
    }
    
    /**
     * Método que permite dar de alta la reserva de un espacio.
     * @param   reserva La reserva a dar de alta en la BBDD
     * @throws  RemoteException
     * @throws  GestorAulasException
     */
    public void insertarReserva(ReservaDTO reserva) throws RemoteException,
            GestorAulasException {
        
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            IReservaDAO dao = factory.getReservaDAO();
            dao.insertarReserva(reserva);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_ALTA_RESERVA
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_ALTA_RESERVA
                    + Constantes.SL + daoE.getMessage());
        }
    }   
    
    public void actualizarReserva(ReservaDTO reserva) throws RemoteException,
            GestorAulasException {
        
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            IReservaDAO dao = factory.getReservaDAO();
            dao.actualizarImporteReserva(reserva);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_ALTA_RESERVA
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_ALTA_RESERVA
                    + Constantes.SL + daoE.getMessage());
        }
    }    
    
    public void insertarSolicitud(SolicitudDTO solicitud) throws RemoteException,
            GestorAulasException {
        
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            dao.insertarSolicitud(solicitud);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_MODIFICAR_SOLICITUD
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_MODIFICAR_SOLICITUD
                    + Constantes.SL + daoE.getMessage());
        }
    }   
    
    public ReservaDTO getReserva(int idReserva) throws RemoteException,
            GestorAulasException {

        ReservaDTO reserva = new ReservaDTO();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            IReservaDAO dao = factory.getReservaDAO();
            reserva = dao.getReserva(idReserva);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_CONSULTA_RESERVA
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_CONSULTA_RESERVA
                    + Constantes.SL + daoE.getMessage());
        }
        return reserva;
    }

    public ReservaDTO getDetalleReserva(int idReserva) throws RemoteException,
            GestorAulasException {

        ReservaDTO reserva = new ReservaDTO();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            IReservaDAO dao = factory.getReservaDAO();
            reserva = dao.getDetalleReserva(idReserva);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_CONSULTA_RESERVA
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_CONSULTA_RESERVA
                    + Constantes.SL + daoE.getMessage());
        }
        return reserva;
    }

    @Override
    public List<ReservaDTO> listaReservas() throws GestorAulasException, RemoteException {
        List<ReservaDTO> reservas = new ArrayList<ReservaDTO>();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            reservas = dao.listaReservas();

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_RESERVAS
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_RESERVAS
                    + Constantes.SL + daoE.getMessage());
        }
        return reservas;
    }
        public List<ReservaDTO> listaReservas(LocalizacionDTO local,
            List<Integer> estados, String FechaDesde, String FechaHasta) throws
            GestorAulasException, RemoteException {
        List<ReservaDTO> reservas = new ArrayList<ReservaDTO>();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            IReservaDAO dao = factory.getReservaDAO();
            reservas = dao.listaReservas(local,estados,FechaDesde,FechaHasta);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_RESERVAS
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_RESERVAS
                    + Constantes.SL + daoE.getMessage());
        }
        return reservas;
    }
        
    @Override
    public List<AulaDTO> listaAulas(LocalizacionDTO local,
            List<Integer> estados, String fechaDesde, String fechaHasta) throws
            GestorAulasException, RemoteException {
        List<AulaDTO> aulas = new ArrayList<AulaDTO>();
        try {
            DAOFactory factory = DAOFactory.getDAOFactory();
            ISolicitudDAO dao = factory.getSolicitudDAO();
            aulas = dao.listaAulas(local,estados,fechaDesde,fechaHasta);

            // Liberamos recursos
            factory = null;
            dao = null;

        } catch (DAOFactoryException daoF) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_AULAS
                    + Constantes.SL + daoF.getMessage());
        } catch (DataBaseDAOException daoE) {
            throw new GestorAulasException(GestorAulasException.ERROR_LISTA_AULAS
                    + Constantes.SL + daoE.getMessage());
        }
        return aulas;
    }
}
